#ifndef MODEL_H
#define MODEL_H
#include <SDL.h>
#include <iostream>
#include <list>
#include <string>
using std::string;
using std::list;

#include "clock.h"
#include "sprite.h"
#include "multiSprite.h"
#include "world.h"
#include "gamedata.h"
#include "frameFactory.h"
#include "multiFrameFactory.h"
#include "player.h"
#include "sound.h"
#include "explodingSprite.h"
#include "collisionStrategy.h"
#include "ball.h"
#include "item.h"
#include "ioManager.h"
#include "score.h"
//#include "spriteFactory.h"

class Model {
public:
  Model ();
  ~Model ();
  void draw() const;
  void update();
  
  void makeBricks();
  void drawBricks() const;
  void updateBricks(unsigned ticks);
  void deleteBricks();
  void resetBricks();

  void emitBall();
  
  void drawItems() const;
  void updateItems(unsigned ticks);
  void deleteItems();
  void generateItem(const Sprite & s);
  void obtainItem(const Item& item);
  
  void drawBalls() const;
  void updateBalls(unsigned ticks);
  void resetBalls();
  void addBalls();
  void deleteBalls();
  
  void giveHelp();
  void pause();
  bool isPaused() const; 
  
  void drawHelp() const;
  void drawFps() const;
  void drawCount() const;
  void drawLife() const;
  void drawScore() const;
  
  void toggleHelp(){showHelp = !showHelp;pause();}
  
  void move(int direction){
	  player->move(direction);
	  }
  void stop(){
	  player->stop();
	  }
  void playSound(int index);
  void toggleBgm();
  void explode();
  void drawExplosions() const;
  void updateExplosions(unsigned ticks);
  void deleteExplosions();
  
  void playerCollision(Player* p, Ball* b);
  void bricksCollision(Ball *b);
  void itemsCollision();
  
  void ballsCollision();
  
  void start();
  
  const World& getWorld() const {return world;}
private:
  const Gamedata* gamedata;
  IOManager *io;
  CollisionStrategy* strategy;
  SDLSound *sound;
  Clock clock;
  SDL_Surface *screen;
  FrameFactory* factory;
  MultiFrameFactory* mfactory;
  World world;
  Player * player;
  Ball * ball;
  std::list<Ball*> balls;
  std::list<Sprite*> bricks;
  std::list<Item*> items;
  std::list<ExplodingSprite*> explosions;
  Score score;
  bool showHelp;
  Model(const Model&);
  Model& operator=(const Model&);
};
#endif
